package com.hghivln.controller.system;

import com.hghivln.constants.Constants;
import com.hghivln.constants.HttpStatus;
import com.hghivln.pojo.domain.LoginInfo;
import com.hghivln.pojo.domain.Menu;
import com.hghivln.pojo.domain.SimpleUser;
import com.hghivln.pojo.dto.LoginDto;
import com.hghivln.pojo.vo.ActiverUser;
import com.hghivln.pojo.vo.AjaxResult;
import com.hghivln.pojo.vo.MenuTreeVo;
import com.hghivln.service.LoginInfoService;
import com.hghivln.service.MenuService;
import com.hghivln.utils.ShiroUtils;
import com.hghivln.utils.AddressUtils;
import com.hghivln.utils.IpUtils;
import eu.bitwalker.useragentutils.UserAgent;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("login")
@Log4j2
public class LoginController {

    @Autowired
    private MenuService menuService;

    @Autowired
    private LoginInfoService loginInfoService;

    /**
     * 登录
     */
    @PostMapping("doLogin")
    public AjaxResult login(@RequestBody @Validated LoginDto loginDto,HttpServletRequest request) {
        AjaxResult ajax = AjaxResult.success();
        String password = loginDto.getPassword();
        String username = loginDto.getUsername();
        UsernamePasswordToken authenticationToken = new UsernamePasswordToken(username, password);
        Subject subject = SecurityUtils.getSubject();
        // 记录日志
        LoginInfo loginInfo = createLoginInfo(request);
        loginInfo.setLoginAccount(loginDto.getUsername());

        try {
            subject.login(authenticationToken);
            Serializable token = subject.getSession().getId();
            ajax.put(Constants.TOKEN,token);

            loginInfo.setMsg("登录成功");
            loginInfo.setLoginStatus(Constants.LOGIN_SUCCESS);
            loginInfo.setUserName(ShiroUtils.getActiverUser().getUser().getUserName());

        } catch (Exception e) {
            log.error("用户名或密码不正确",e);
            ajax = AjaxResult.error(HttpStatus.USERNAME_OR_PASSWORD_ERROR, "用户名或密码不正确");

            loginInfo.setMsg("用户名或密码不正确");
            loginInfo.setLoginStatus(Constants.LOGIN_ERROR);

            e.printStackTrace();
        }
        loginInfoService.saveLoginInfo(loginInfo);
        return ajax;
    }

    /**
     * 获取用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo() {
        ActiverUser activerUser = ShiroUtils.getActiverUser();
        AjaxResult ajax = AjaxResult.success();
        ajax.put("username",activerUser.getUser());
        ajax.put("picture",activerUser.getUser().getPicture());
        ajax.put("roles",activerUser.getRoles());
        ajax.put("permissions",activerUser.getPermissions());
        return ajax;
    }

    /**
     * 退出登录
     */
    @PostMapping("logout")
    public AjaxResult logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return AjaxResult.success("用户退出成功");
    }

    /**
     * 加载左边菜单栏信息
     */
    @GetMapping("getMenus")
    public AjaxResult getMenus() {
        boolean isAdmin = ShiroUtils.getCurrentUser().getUserType().equals(Constants.USER_ADMIN);
        SimpleUser simpleUser = null;
        if (!isAdmin) {
            simpleUser = new SimpleUser(ShiroUtils.getCurrentUser().getUserId(), ShiroUtils.getCurrentUser().getUserName());
        }
        List<Menu> menus = menuService.selectMenuTree(isAdmin, simpleUser);
        List<MenuTreeVo> menuTreeVos = new ArrayList<>();
        for (Menu menu : menus) {
            menuTreeVos.add(new MenuTreeVo(menu.getMenuId().toString(),menu.getPath()));
        }
        return AjaxResult.success(menuTreeVos);
    }

    /**
     * 日志
     */
    private LoginInfo createLoginInfo(HttpServletRequest request) {
        LoginInfo loginInfo = new LoginInfo();
        // 登录IP地址
        String ipAddr = IpUtils.getIpAddr(request);
        // 登录地点
        String location = AddressUtils.getRealAddressByIP(ipAddr);
        // 操作系统
        UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("user-agent"));
        String os = userAgent.getOperatingSystem().getName();
        // 浏览器类型
        String browser = userAgent.getBrowser().getName();

        loginInfo.setIpAddr(ipAddr);
        loginInfo.setLoginLocation(location);
        loginInfo.setOs(os);
        loginInfo.setBrowser(browser);
        loginInfo.setLoginTime(new Date());
        loginInfo.setLoginType(Constants.LOGIN_TYPE_SYSTEM);


        return loginInfo;
    }

}
